package mus2.client;

/*
 * UNPUBLISHED PROPRIETARY INFORMATION
 * Copyright (c) 2007-2008 Sentilla Corporation
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Sentilla Corporation ("Confidential Information"). Disclosure of this
 * Confidential Information is prohibited, and its use shall be in
 * compliance with terms of the license agreement with Sentilla Corporation.
 */

/**
 * A stub host application that listen for messages from the mote network.
 *
 * @author <a href="mailto:info@sentilla.com">Sentilla Corporation</a>
 */

import java.text.DecimalFormat;

import mus2.mote.UltraSonicMessage;

import com.sentilla.host.client.HostClient;
import com.sentilla.net.Receiver;
import com.sentilla.net.ReceiverDriver;


import processing.core.*;

public class UltraSonicClientApp extends PApplet {

	
	//Instantiate basic components

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	Receiver receiver;

	UltraSonicMessage umsg = new UltraSonicMessage();
	
	PFont font;
	public void setup()
	{

		// Set up the playing field
		size(1000, 800);
		stroke(255);
		frameRate(60);
		background(0);
		font =  createFont("FFScala", 32);
		textFont(font, width/10);
		redraw();

		/* create the host server connection */
		HostClient host = new HostClient();
		try
		{
			host.connect(); 
		}
		catch (Exception e){}

		
		//Start receiver
		receiver = ReceiverDriver.create(UltraSonicMessage.class);
		receiver.cancel();
		receiver.setReceive().submit();
	
	}

	double distance;
	double olddistance=0;
    String out = "";
	
	public void draw()
	{
	

		if (receiver.isDone())
		{
			background(0);
			umsg = (UltraSonicMessage) receiver.getData();
			receiver.setReceive().submit();
			addValue(heightArr,umsg.meter);
			if ( counter < arraysize) counter++;
			animcounter = 0;

		}
		
		
		background(0);

		distance = umsg.meter/4 + 3*olddistance/4;
		olddistance = distance;
		int bar = (int)(distance/200*width);
		rect(0, height/3+height/9, bar, height/10);
		DecimalFormat df = new DecimalFormat( "0.00" );
		out = df.format( distance ) + " meter";
		textFont(font, width/10);
		text(out,0,height/3);	
		
		plotlineanim(6*height/7,height/7,heightArr,255,255,255," m");
		if (animcounter < animlimit) animcounter++;
		

	}
	public static void main(String args[]) {

		PApplet.main(new String[] { "--present", "mus2.client.UltraSonicClientApp" });

	}
	
	void addValue(double[] dubArr, double addVal)
	{
		for (int i = dubArr.length-1; i > 0; i--)
		{
			dubArr[i] = dubArr[i - 1];
		}
		dubArr[0] = addVal;
	}

	float animcounter = 0;
	float animlimit = 200;
	int arraysize = 30;
	int counter = 0;
	float[] ypoints = new float[arraysize];
	float[] xpoints = new float[arraysize];
	double[] heightArr = new double[arraysize];
	       
	void plotlineanim(float base, float maxheight, double[] dubArr, int r, int g, int b, String units)
	{

		float max  = 0;
		float min  = 500;
		float range = max - min;
		
		for (int i = 0; i < dubArr.length-1; i ++)
		{
			if (dubArr[i] > max) max = (float)dubArr[i];
			if (dubArr[i] < min && dubArr[i] != 0) min = (float)dubArr[i];
		}
		range = max - min;;

		
		float oldmax = (float) dubArr[1];
		float oldmin= (float)dubArr[1];
		float oldrange;
		
		for (int i = 1; i < dubArr.length; i ++)
		{
			if (dubArr[i] > oldmax) oldmax = (float)dubArr[i];
			if (dubArr[i] < oldmin && dubArr[i] != 0) oldmin = (float)dubArr[i];
		}
		oldrange = oldmax - oldmin;
		
		float xposnow;
		float xposold;
		
		float yposnow;
		float yposold;
		
		
		//calculate points
		for (float i = 0; i < dubArr.length; i ++)
		{
			//Determine X Position
			 xposnow = (width-100) - ((arraysize - counter) + i)/((float)dubArr.length)*(width-100);
			 //Determine Y Position, auto scale
			 yposnow = base-(float)((dubArr[(int)i]-min)/range * maxheight);
			 
			 if (counter == arraysize && i != 0)
			 {
				 xposold = (width-100) - ((arraysize - counter) + i-1)/((float)dubArr.length)*(width-100);
				// yposold = base-(float)((dubArr[(int)i]-oldmin)/oldrange * maxheight);
				 //yposold = yposnow;
			 }
			 else 
			{
				 xposold = xposnow;
				 //yposold = yposnow;
			}
			 
			 if (i != 0)
			 {
				// xposold = (width-100) - ((arraysize - counter) + i-1)/((float)dubArr.length)*(width-100);
				yposold = base-(float)((dubArr[(int)i]-oldmin)/oldrange * maxheight);
				 //yposold = yposnow;
			 }
			 else 
			{
				 //xposold = xposnow;
				 yposold = yposnow;
			}
			 
			 xpoints[(int)i] = ((animcounter*xposnow) + (animlimit-animcounter)*xposold)/animlimit;
			 ypoints[(int)i] = ((animcounter*yposnow) + (animlimit-animcounter)*yposold)/animlimit;
			 if (animcounter < animlimit)animcounter ++;
			

		
			 
		}
		
		 //Draw Dots
		for (int i = 0; i < dubArr.length; i ++)
		{
			
			 
			
			 ellipseMode(CENTER);
			 stroke(r,g,b);
			 if (i == 0)
			 {
				 fill(
						 (float)r*(animcounter/animlimit),
						 (float)g*(animcounter/animlimit),
						 (float)b*(animcounter/animlimit)
					);
				 float rad = width/100 * animcounter/animlimit;
				 if (counter > (int)i) 	ellipse(xpoints[i], ypoints[i], rad, rad);
			 }
			 else if (i == dubArr.length-1)
			 {
				 fill(
						 (float)r*(1-(animcounter/animlimit)),
						 (float)g*(1-(animcounter/animlimit)),
						 (float)b*(1-(animcounter/animlimit))
					);
				 float rad = width/100 * (1-(animcounter/animlimit));
				 if (counter > (int)i) 	ellipse(xpoints[i], ypoints[i], rad, rad);
			 }

			 else 
				 {
				 fill(r,g,b);
				 if (counter > (int)i) ellipse(xpoints[i], ypoints[i], width/100, width/100);
				 }

	
		}
		
		//connect dots
		for (int i = 0; i < dubArr.length-1; i++)
		{
			 if (i == 0)
			 {
				 stroke(
						 (float)r*(animcounter/animlimit),
						 (float)g*(animcounter/animlimit),
						 (float)b*(animcounter/animlimit)
					);
			 }
			 else if (i == dubArr.length-2)
			 {
				 stroke(
						 (float)r*(1-(animcounter/animlimit)),
						 (float)g*(1-(animcounter/animlimit)),
						 (float)b*(1-(animcounter/animlimit))
					);
			 }
			 else stroke(r,g,b);
			if (counter > (int)i+1) curve(
					xpoints[i]*2/3+xpoints[i+1]/3,ypoints[i]*2/3+ypoints[i+1]/3,
					xpoints[i],ypoints[i],
					xpoints[i+1],ypoints[i+1],
					xpoints[i]/3+xpoints[i+1]*2/3,ypoints[i]/3+ypoints[i+1]*2/3	
					                    );
		}
		
		//Show current value
		float now = (float)dubArr[0];
		float then = (float)dubArr[1];
		now = ((animcounter*now) + (animlimit-animcounter)*then)/animlimit;
		now = round(now*10);
		now = now/10;
		String out = String.valueOf(now)+" "+units;
		fill(r,g,b);
		textFont(font, width/60);
		textAlign(RIGHT);
		text(out,width-10,base-maxheight/2);
		
		//Show min value
		max = ((animcounter*max) + (animlimit-animcounter)*oldmax)/animlimit;
		max = round(max*10);
		max = max/10;
		out = String.valueOf(max)+" "+units;
		fill(r,g,b);
		textFont(font, width/60);
		textAlign(LEFT);
		text(out,10,base-maxheight-20);

		//Show max value
		min = ((animcounter*min) + (animlimit-animcounter)*oldmin)/animlimit;
		min = round(min*10);
		min = min/10;
		out = String.valueOf(min)+" "+units;
		fill(r,g,b);
		textFont(font, width/60);
		textAlign(LEFT);
		text(out,10,base+20);
		
	}
	void plottime (float base, double[] timeArr)
	{
		double timenow = timeArr[0]/1000;
		double timeold = timeArr[timeArr.length-1]/1000;
		double out = timeold - timenow;
		String old = String.valueOf(out);
		fill(255);
		textFont(font, width/60);
		text(old,width/(float)arraysize,base);
	    text("0",width-width/(float)arraysize,base);
	}
	
	double findMax(double[] dubArr)
	{
		double dubMax = dubArr[0];
		for (int i = 0; i < dubArr.length; i++)
		{
			if (dubArr[i]>dubMax) dubMax = dubArr[i];
		}
		
		return dubMax;
	}
	
	double findMin(double[] dubArr)
	{
		double dubMin = dubArr[0];
		for (int i = 0; i < dubArr.length; i++)
		{
			if (dubArr[i]<dubMin) dubMin = dubArr[i];
		}
		
		return dubMin;
	}


	double findMinNotZero(double[] dubArr)
	{
		double dubMin = dubArr[0];
		for (int i = 0; i < dubArr.length; i++)
		{
			if (dubArr[i]<dubMin && dubArr[i] != 0) dubMin = dubArr[i];
		}
	
		return dubMin;
	}
}
